﻿// -----------------------------------------------------------------------
//    This file is part of TSGE.
//
//    TSGE is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 2 of the License, or
//    (at your option) any later version.
//
//    TSGE is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with TSGE.  If not, see <http://www.gnu.org/licenses/>.
// -----------------------------------------------------------------------

namespace tsge.Classes
{
    using System;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Media;

    /// <summary>
    /// Player Class Implementation
    /// 
    ///     Inherits:
    ///         - INotifyPropertyChanged
    /// </summary>
    public class Player : INotifyPropertyChanged
    {
        /// <summary>
        /// Internal copy of the player profile file (if any) that this profile is from.
        /// </summary>
        private String m_vPlayerFile;

        /// <summary>
        /// Internal copy of the player game version.
        /// </summary>
        private Int32 m_vGameVersion;

        /// <summary>
        /// Internal copy of the player name.
        /// </summary>
        private String m_vPlayerName;

        /// <summary>
        /// Internal copy of the player difficulty.
        /// </summary>
        private Byte m_vDifficulty;

        /// <summary>
        /// Internal copy of the player hair.
        /// </summary>
        private Int32 m_vHair;

        /// <summary>
        /// Internal copy of the player male flag.
        /// </summary>
        private Boolean m_vIsMale;

        /// <summary>
        /// Internal copy of the player health.
        /// </summary>
        private Int32 m_vHealth;

        /// <summary>
        /// Internal copy of the player max health.
        /// </summary>
        private Int32 m_vHealthMax;

        /// <summary>
        /// Internal copy of the player mana.
        /// </summary>
        private Int32 m_vMana;

        /// <summary>
        /// Internal copy of the player max mana.
        /// </summary>
        private Int32 m_vManaMax;

        /// <summary>
        /// Internal copy of the player hair color.
        /// </summary>
        private Color m_vHairColor;

        /// <summary>
        /// Internal copy of the player skin color.
        /// </summary>
        private Color m_vSkinColor;

        /// <summary>
        /// Internal copy of the player eye color.
        /// </summary>
        private Color m_vEyeColor;

        /// <summary>
        /// Internal copy of the player shirt color.
        /// </summary>
        private Color m_vShirtColor;

        /// <summary>
        /// Internal copy of the player undershirt color.
        /// </summary>
        private Color m_vUnderShirtColor;

        /// <summary>
        /// Internal copy of the player pants color.
        /// </summary>
        private Color m_vPantsColor;

        /// <summary>
        /// Internal copy of the player shoes color.
        /// </summary>
        private Color m_vShoesColor;

        /// <summary>
        /// Internal copy of the player armor items.
        /// </summary>
        private Item[] m_vArmor;

        /// <summary>
        /// Internal copy of the player vanity items.
        /// </summary>
        private Item[] m_vVanity;

        /// <summary>
        /// Internal copy of the player accessory items.
        /// </summary>
        private Item[] m_vAccessories;

        /// <summary>
        /// Internal copy of the player inventory items.
        /// </summary>
        private Item[] m_vInventory;

        /// <summary>
        /// Internal copy of the player bank1 items.
        /// </summary>
        private Item[] m_vBank1;

        /// <summary>
        /// Internal copy of the player bank2 items.
        /// </summary>
        private Item[] m_vBank2;

        /// <summary>
        /// Internal copy of the player buffs.
        /// </summary>
        private Buff[] m_vBuffs;

        /// <summary>
        /// Internal copy of the player server entries.
        /// </summary>
        private ServerEntry[] m_vServerEntries;

        /// <summary>
        /// Internal copy of the player hotbar locked flag.
        /// </summary>
        private Boolean m_vIsHotbarLocked;

        /// <summary>
        /// Public PropertyChanged event to register onto.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Default Constructor
        /// </summary>
        public Player()
        {
            this.GameVersion = Terraria.GAME_VERSION;
            this.Name = "Player";
            this.Difficulty = 0;
            this.Hair = 0;
            this.IsMale = true;

            this.Health = 100;
            this.HealthMax = 100;
            this.Mana = 100;
            this.ManaMax = 100;

            this.HairColor = (Color)ColorConverter.ConvertFromString("#FFD75A37");
            this.SkinColor = (Color)ColorConverter.ConvertFromString("#FFFF7D4B");
            this.EyeColor = (Color)ColorConverter.ConvertFromString("#FF695A4B");
            this.ShirtColor = (Color)ColorConverter.ConvertFromString("#FFAFA58C");
            this.UnderShirtColor = (Color)ColorConverter.ConvertFromString("#FFA0B4D7");
            this.PantsColor = (Color)ColorConverter.ConvertFromString("#FFFFE6AF");
            this.ShoesColor = (Color)ColorConverter.ConvertFromString("#FFA06A3C");

            this.Armor = new Item[3];
            this.Vanity = new Item[3];
            this.Accessories = new Item[5];

            this.Inventory = new Item[48];
            this.Bank1 = new Item[20];
            this.Bank2 = new Item[20];
            this.Buffs = new Buff[10];
            this.ServerEntries = new ServerEntry[200];

            var defaultItem = (from item in Terraria.Instance.Items
                               where item.NetID == 0
                               select item).SingleOrDefault() as Item;

            for (int x = 0; x < this.Armor.Length; x++)
            {
                this.Armor[x] = defaultItem.Clone() as Item;
            }

            for (int x = 0; x < this.Vanity.Length; x++)
            {
                this.Vanity[x] = defaultItem.Clone() as Item;
            }

            for (int x = 0; x < this.Accessories.Length; x++)
            {
                this.Accessories[x] = defaultItem.Clone() as Item;
            }

            for (int x = 0; x < 48; x++)
            {
                this.Inventory[x] = defaultItem.Clone() as Item;
            }

            for (int x = 0; x < this.Bank1.Length; x++)
            {
                this.Bank1[x] = defaultItem.Clone() as Item;
            }

            for (int x = 0; x < this.Bank2.Length; x++)
            {
                this.Bank2[x] = defaultItem.Clone() as Item;
            }

            for (int x = 0; x < this.Buffs.Length; x++)
            {
                this.Buffs[x] = (from Buff b in Terraria.Instance.Buffs
                                 where b.Id == 0
                                 select b).SingleOrDefault().Clone() as Buff;
            }

            for (int x = 0; x < this.ServerEntries.Length; x++)
            {
                this.ServerEntries[x] = new ServerEntry();
            }

            this.IsHotbarLocked = false;

            this.File = String.Empty;
        }

        /// <summary>
        /// Invokes the PropertyChanged event if one is set.
        /// </summary>
        /// <param name="propName">Name of the property being updated.</param>
        private void NotifyPropertyChanged(String propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

        /// <summary>
        /// Gets or sets the profile file of this player.
        /// </summary>
        public String File
        {
            get { return this.m_vPlayerFile; }
            set { this.m_vPlayerFile = value; this.NotifyPropertyChanged("File"); }
        }

        /// <summary>
        /// Gets or sets the game version of this player.
        /// </summary>
        public Int32 GameVersion
        {
            get { return this.m_vGameVersion; }
            set { this.m_vGameVersion = value;  this.NotifyPropertyChanged("GameVersion"); }
        }

        /// <summary>
        /// Gets or sets the name of this player.
        /// </summary>
        public String Name
        {
            get { return this.m_vPlayerName; }
            set { this.m_vPlayerName = value; this.NotifyPropertyChanged("Name"); }
        }

        /// <summary>
        /// Gets or sets the difficulty of this player.
        /// </summary>
        public Byte Difficulty
        {
            get { return this.m_vDifficulty; }
            set { this.m_vDifficulty = value; this.NotifyPropertyChanged("Difficulty"); }
        }

        /// <summary>
        /// Gets or sets the hair of this player.
        /// </summary>
        public Int32 Hair
        {
            get { return this.m_vHair; }
            set { this.m_vHair = value; this.NotifyPropertyChanged("Hair"); }
        }

        /// <summary>
        /// Gets or sets the male flag of this player.
        /// </summary>
        public Boolean IsMale
        {
            get { return this.m_vIsMale; }
            set { this.m_vIsMale = value; this.NotifyPropertyChanged("Male"); }
        }

        /// <summary>
        /// Gets or sets the health of this player.
        /// </summary>
        public Int32 Health
        {
            get { return this.m_vHealth; }
            set { this.m_vHealth = value; this.NotifyPropertyChanged("Health"); }
        }

        /// <summary>
        /// Gets or sets the max health of this player.
        /// </summary>
        public Int32 HealthMax
        {
            get { return this.m_vHealthMax; }
            set { this.m_vHealthMax = value; this.NotifyPropertyChanged("HealthMax"); }
        }

        /// <summary>
        /// Gets or sets the mana of this player.
        /// </summary>
        public Int32 Mana
        {
            get { return this.m_vMana; }
            set { this.m_vMana = value; this.NotifyPropertyChanged("Mana"); }
        }

        /// <summary>
        /// Gets or sets the max mana of this player.
        /// </summary>
        public Int32 ManaMax
        {
            get { return this.m_vManaMax; }
            set { this.m_vManaMax = value; this.NotifyPropertyChanged("ManaMax"); }
        }

        /// <summary>
        /// Gets or sets the hair color of this player.
        /// </summary>
        public Color HairColor
        {
            get { return this.m_vHairColor; }
            set { this.m_vHairColor = value; this.NotifyPropertyChanged("HairColor"); }
        }

        /// <summary>
        /// Gets or sets the skin color of this player.
        /// </summary>
        public Color SkinColor
        {
            get { return this.m_vSkinColor; }
            set { this.m_vSkinColor = value; this.NotifyPropertyChanged("SkinColor"); }
        }

        /// <summary>
        /// Gets or sets the eye color of this player.
        /// </summary>
        public Color EyeColor
        {
            get { return this.m_vEyeColor; }
            set { this.m_vEyeColor = value; this.NotifyPropertyChanged("EyeColor"); }
        }

        /// <summary>
        /// Gets or sets the shirt color of this player.
        /// </summary>
        public Color ShirtColor
        {
            get { return this.m_vShirtColor; }
            set { this.m_vShirtColor = value; this.NotifyPropertyChanged("ShirtColor"); }
        }

        /// <summary>
        /// Gets or sets the undershirt color of this player.
        /// </summary>
        public Color UnderShirtColor
        {
            get { return this.m_vUnderShirtColor; }
            set { this.m_vUnderShirtColor = value; this.NotifyPropertyChanged("UnderShirtColor"); }
        }

        /// <summary>
        /// Gets or sets the pants color of this player
        /// </summary>
        public Color PantsColor
        {
            get { return this.m_vPantsColor; }
            set { this.m_vPantsColor = value; this.NotifyPropertyChanged("PantsColor"); }
        }

        /// <summary>
        /// Gets or sets the shoes color of this player.
        /// </summary>
        public Color ShoesColor
        {
            get { return this.m_vShoesColor; }
            set { this.m_vShoesColor = value; this.NotifyPropertyChanged("ShoesColor"); }
        }

        /// <summary>
        /// Gets or sets the armor items of this player.
        /// </summary>
        public Item[] Armor
        {
            get { return this.m_vArmor; }
            set { this.m_vArmor = value; this.NotifyPropertyChanged("Armor"); }
        }

        /// <summary>
        /// Gets or sets the vanity items of this player.
        /// </summary>
        public Item[] Vanity
        {
            get { return this.m_vVanity; }
            set { this.m_vVanity = value; this.NotifyPropertyChanged("Vanity"); }
        }

        /// <summary>
        /// Gets or sets the accessory items of this player.
        /// </summary>
        public Item[] Accessories
        {
            get { return this.m_vAccessories; }
            set { this.m_vAccessories = value; this.NotifyPropertyChanged("Accessories"); }
        }

        /// <summary>
        /// Gets or sets the inventory items of this player.
        /// </summary>
        public Item[] Inventory
        {
            get { return this.m_vInventory; }
            set { this.m_vInventory = value; this.NotifyPropertyChanged("Inventory"); }
        }

        /// <summary>
        /// Gets or sets the bank1 items of this player.
        /// </summary>
        public Item[] Bank1
        {
            get { return this.m_vBank1; }
            set { this.m_vBank1 = value; this.NotifyPropertyChanged("Bank1"); }
        }

        /// <summary>
        /// Gets or sets the bank2 items of this player.
        /// </summary>
        public Item[] Bank2
        {
            get { return this.m_vBank2; }
            set { this.m_vBank2 = value; this.NotifyPropertyChanged("Bank2"); }
        }

        /// <summary>
        /// Gets or sets the buffs of this player.
        /// </summary>
        public Buff[] Buffs
        {
            get { return this.m_vBuffs; }
            set { this.m_vBuffs = value; this.NotifyPropertyChanged("Buffs"); }
        }

        /// <summary>
        /// Gets or sets the server entries of this player.
        /// </summary>
        public ServerEntry[] ServerEntries
        {
            get { return this.m_vServerEntries; }
            set { this.m_vServerEntries = value; this.NotifyPropertyChanged("ServerEntries"); }
        }

        /// <summary>
        /// Gets or sets the is hotbar locked flag of this player.
        /// </summary>
        public Boolean IsHotbarLocked
        {
            get { return this.m_vIsHotbarLocked; }
            set { this.m_vIsHotbarLocked = value; this.NotifyPropertyChanged("IsHotbarLocked"); }
        }
    }
}
